
package com.dkm.modules.sys.card.controller;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.dkm.commons.BaseController;
import com.dkm.commons.Response;
import com.dkm.exception.ServiceException;
import com.dkm.modules.sys.user.mapper.CustomerMapper;
import com.dkm.modules.sys.user.mapper.UserMapper;
import com.dkm.modules.sys.user.model.Customer;
import com.dkm.modules.sys.user.model.User;
import com.dkm.modules.wx.card.model.Card;
import com.dkm.modules.wx.card.model.RechargeRecods;
import com.dkm.modules.wx.card.model.UseRecods;
import com.dkm.modules.wx.card.service.CardService;
import com.dkm.util.excel.CellData;
import com.dkm.util.excel.ExcelData;
import com.dkm.util.excel.ReadExcelUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName CardController
 * @Description: IC卡控制器
 * @Author yangbin
 * @Date 2019-09-13 12:50
 * @Version V1.0
 **/
@Api(tags = "A5 卡管理")
@RestController
@RequestMapping("/sysCard")
public class SysCardController extends BaseController {

    private final static Logger logger = LoggerFactory.getLogger(SysCardController.class);
    @Autowired
    private CardService cardService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private CustomerMapper customerMapper;

    @ApiOperation("查询注册用户下所有的未挂失的卡")
    @GetMapping("/getCardListByCustomerId")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response<List<Card>> getCradList(@ApiParam("注册用户id") @RequestParam(value = "customerId") Integer customerId) {

        // 获取注册用户所有的卡
        List<Card> cards = cardService.getCardsByCustomerId(customerId);

        return Response.ok(cards);
    }

    @ApiOperation("转账")
    @PostMapping("/transferAccounts")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response transferAccounts(@ApiParam("注册用户Id") @RequestParam("customerId") Integer customerId,
                                     @ApiParam("转入卡号") @RequestParam("cardNo") String cardNo,
                                     @ApiParam("转账金额,单位元") @RequestParam("amount") BigDecimal amount) {

        Customer customer = customerMapper.selectById(customerId);
        if (Objects.isNull(customer)) {
            throw new ServiceException("用户不存在");
        }

        // 转账操作
        cardService.transferAccounts(customer.getWeiXinOpenId(), cardNo, amount, getUserInfo());

        return Response.ok();
    }

    @ApiOperation("充值卡")
    @PostMapping("/rechargeCard")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response rechargeCard(@ApiParam("卡号") @RequestParam("cardNo") String cardNo,
                                 @ApiParam("充值金额") @RequestParam("amount") BigDecimal amount) {
        logger.info("充值卡片,编号：{},金额:{}" + cardNo, amount);

        return cardService.rechargeCard(cardNo, amount, getUserInfo());
    }

    @ApiOperation("新增卡片")
    @PostMapping("/addCard")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response addCard(@ApiParam("卡数据") @RequestBody Card card) {
        logger.info("新增卡片,编号：" + card.getCardNo());
        /*设置卡片的状态为正常*/
        card.setState("6003");// 未启用
        return cardService.addCard(card);
    }

    @ApiOperation("挂失卡")
    @GetMapping("/lossCard")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response lossCard(@ApiParam("卡号") @RequestParam("cardNo") String cardNo) {
        logger.info("挂失卡,卡号：" + cardNo);
        return cardService.lossCard(cardNo);
    }

    @ApiOperation(value = "获取卡列表", notes = "pageNo,pageSize必填")
    @GetMapping("/getCardList")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response<IPage<Card>> getCardList(@ApiParam("代理商Id") @RequestParam(value = "userId", required = false) String userId,
                                             @ApiParam("关键字") @RequestParam(value = "keyWord", required = false) String keyWord,
                                             @ApiParam("页数") @RequestParam("pageNo") int pageNo,
                                             @ApiParam("每页显示数") @RequestParam("pageSize") int pageSize) {
        Page<Card> page = new Page<>(pageNo, pageSize);
        /*查询卡列表*/
        Map<String, Object> params = new HashMap<>();
        params.put("userId", userId);
        params.put("keyWord", keyWord);
        IPage<Card> cardList = cardService.getCardList(params, page);
        return Response.ok(cardList);
    }

    @ApiOperation("编辑卡")
    @PostMapping("/editCard")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response editCard(@RequestBody Card card) {
        logger.info("编辑卡，卡号：" + card.getCardNo());
        /*设置更新时间*/
        card.setUpdateTime(new Date());
        cardService.updateCard(card);
        return Response.ok();
    }


    @ApiOperation("卡使用记录")
    @GetMapping("/getUseRecods")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response<UseRecods> getUseRecods(@ApiParam("卡号") @RequestParam("cardNo") String cardNo,
                                            @ApiParam("页数") @RequestParam("pageNo") int pageNo,
                                            @ApiParam("每页显示数") @RequestParam("pageSize") int pageSize) {
        logger.info("获取卡使用记录");
        Page<UseRecods> page = new Page<>(pageNo, pageSize);
        IPage<UseRecods> Recods = cardService.getUseRecods(page, cardNo);
        return new Response(Recods);
    }

    @ApiOperation("卡充值记录")
    @GetMapping("/getRechargeRecods")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response geRechargeRecods(@ApiParam("卡号") @RequestParam("cardNo") String cardNo,
                                     @ApiParam("页数") @RequestParam("pageNo") int pageNo,
                                     @ApiParam("每页显示数") @RequestParam("pageSize") int pageSize) {
        logger.info("获取卡充值记录");
        Page<RechargeRecods> page = new Page<>(pageNo, pageSize);
        Map<String, Object> params = new HashMap<>();
        params.put("cardNo", cardNo);
        IPage<RechargeRecods> Recods = cardService.geRechargeRecods(params, page);
        return Response.ok(Recods);
    }

    @ApiOperation("批量上传卡")
    @PostMapping("/uploadCards")
    @ApiImplicitParam(paramType = "header", name = "token", value = "身份认证Token")
    public Response uploadCards(MultipartFile file) {

        List<Card> cards = parseExcelFile(file);

        if (CollectionUtils.isEmpty(cards)) {
            return Response.error(-1, "Excel文件为空.");
        }
        List<Map<String, String>> failedRecords = new ArrayList<>();
        for (Card card : cards) {
            Response response = addCard(card);
            if (response.getMessage().getCode() != 0) {
                Map<String, String> failedMessage = new HashMap<>();
                failedMessage.put("cardNo", card.getCardNo());
                failedMessage.put("message", response.getMessage().getMessage());
                failedRecords.add(failedMessage);
            }
        }
        if (CollectionUtils.isNotEmpty(failedRecords)) {
            return Response.error(200, -1, "批量上传处理错误", failedRecords);
        }
        return Response.ok();
    }

    private List<Card> parseExcelFile(MultipartFile file) {
        ExcelData excelData;
        try {
            excelData = ReadExcelUtil.readTable(file.getInputStream(), file.getOriginalFilename());
        } catch (Exception e) {
            throw new RuntimeException("Excel Parse Failed.");
        }
        List<Card> list = new ArrayList<>();
        if (excelData.getRow() == 0) {
            return list;
        }
        for (Map.Entry<String, List<CellData>> entry : excelData.getData().entrySet()) {
            List<CellData> cellDataList = entry.getValue();
            Card card = new Card();
            for (CellData cellData : cellDataList) {
                if (cellData.getColName().equalsIgnoreCase("卡号")) {
                    card.setCardNo(cellData.getValue());
                }
                if (cellData.getColName().equalsIgnoreCase("余额")) {
                    String value = cellData.getValue();
                    if (StringUtils.isBlank(value)) {
                        value = "0";
                    }
                    card.setSum(new BigDecimal(value));
                }
                if (cellData.getColName().equalsIgnoreCase("手机号")) {
                    card.setMobile(cellData.getValue());
                }
                if (cellData.getColName().equalsIgnoreCase("代理商手机号")) {
                    String mobile = cellData.getValue();
                    if (StringUtils.isNotEmpty(mobile)) {
                        User user = userMapper.getAgentByMobile(mobile);
                        if (user != null) {
                            card.setOperator(user.getId().toString());
                        }
                    }
                }
            }
            list.add(card);
        }

        list = list.stream().filter(card -> StringUtils.isNotBlank(card.getCardNo())).collect(Collectors.toList());

        return list;
    }

}
